﻿#include"stdafx.h"
#ifdef LK_REFLECTION_
namespace LK
{
		index_t ptr<Reflection::LibraryNode>::Compare(ptr<Reflection::LibraryNode> const&n1, ptr<Reflection::LibraryNode> const&n2){
			index_t i = ptr<String>::Compare(n1.GetName(), n2.GetName());
			return i;
		}
		index_t ptr<Reflection::LibraryNode>::StringCompare(ptr<Reflection::LibraryNode> const&n1, ptr<String> const&n2){
			return ptr<String>::Compare(n1.GetName(), n2);
		}
		Reflection::PNamespaceNode& ptr<Reflection::TypeLibrary>::GetGlobleNamespaceRef()const { return Check()->GetGlobleNamespaceRef(); }
		ptr<String> ptr<Reflection::TypeLibrary>::GetSeparatorRef()const { return Check()->Separator; }
		Reflection::PTypeNode ptr<Reflection::TypeLibrary>::GetTypeNodeByInfo(const ptr<Type>&t)const
		{
			if (t==null || !t->IsPureType())return Reflection::PTypeNode();
			return GetTypeNodeByInfo(t->GetID());
		}
		Reflection::PTypeNode ptr<Reflection::TypeLibrary>::GetTypeNodeByInfo(index_t id)const
		{
			if (id == 0)return Reflection::PTypeNode();
			if (id > 0)
			{
				if (Check()->GetStaticTypesRef()->size()<=id)return Reflection::PTypeNode();
				return GetPtr()->GetStaticTypesRef()[id];
			}
			std::map<index_t, Reflection::PTypeNode>::iterator it = Check()->DynamicTypes.find(id);
			if (it == GetPtr()->DynamicTypes.end())return Reflection::PTypeNode();
			return it->second;
		}
		void ptr<Reflection::TypeLibrary>::SetTypeNodeByInfo(const ptr<Type>&t, Reflection::PTypeNode const&node)const{Check()->SetTypeNodeByInfo(t, node);}
	namespace Reflection
	{
		void TypeLibrary::SetTypeNodeByInfo(const ptr<Type>&t, PTypeNode const&node)
		{
			if (t==null)Throw<PInvalidArgumentException>(L"指定的Type为空");
			index_t id = t->GetID();
			if (id == 0)Throw<PInvalidArgumentException>(L"指定的Type的ID为0");
			if (id > 0)
			{
				if (GetStaticTypesRef()->size() <= id)StaticTypes->Resize(id + 1);
				StaticTypes[id] = node;
			}
			else
			{
				std::map<index_t, PTypeNode>::iterator it = DynamicTypes.find(id);
				if (it == DynamicTypes.end())
				{
					if(node!=null)DynamicTypes.insert(std::pair<index_t, PTypeNode>(id, node));
				}
				else
				{
					if (node==null)DynamicTypes.erase(it);
					else it->second = node;
				}
			}
		}
		PNamespaceNode& TypeLibrary::GetGlobleNamespaceRef()
		{
			if (GlobleNamespace==null)GlobleNamespace = new NamespaceNode(L"Globle", this);
			return GlobleNamespace;
		}
		/**
		@brief 获取静态的类型映射（如果映射为空，则自动生成基本类型映射）*/
		ptr<Collection::IArray<PTypeNode>>& TypeLibrary::GetStaticTypesRef()
		{
			//自动添加类型节点：void,bool,s8,s16,i32,s32,s64,u8,u16,ui32,u32,u64,float,double,long double,char,wchar_t
			if (StaticTypes==null)
			{
				StaticTypes = ptr<Collection::IArray<PTypeNode>>(20);
				//在全局命名空间中添加基础类型
				GetGlobleNamespaceRef().FindOrAddTypeNode(L"void", Type::Make<void>());
				GetGlobleNamespaceRef().FindOrAddTypeNode(L"char", Type::Make<char>());
				GetGlobleNamespaceRef().FindOrAddTypeNode(L"int", Type::Make<int>());
				GetGlobleNamespaceRef().FindOrAddTypeNode(L"short", Type::Make<short>());
				GetGlobleNamespaceRef().FindOrAddTypeNode(L"long", Type::Make<long>());
				GetGlobleNamespaceRef().FindOrAddTypeNode(L"long long", Type::Make<long long>());
				GetGlobleNamespaceRef().FindOrAddTypeNode(L"signed char", Type::Make<signed char>());
				GetGlobleNamespaceRef().FindOrAddTypeNode(L"signed short", Type::Make<signed short>());
				GetGlobleNamespaceRef().FindOrAddTypeNode(L"unsigned int", Type::Make<unsigned int>());
				GetGlobleNamespaceRef().FindOrAddTypeNode(L"unsigned long", Type::Make<unsigned long>());
				GetGlobleNamespaceRef().FindOrAddTypeNode(L"unsigned long long", Type::Make<unsigned long long>());
				GetGlobleNamespaceRef().FindOrAddTypeNode(L"unsigned char", Type::Make<unsigned char>());
				GetGlobleNamespaceRef().FindOrAddTypeNode(L"wchar_t", Type::Make<wchar_t>());
				GetGlobleNamespaceRef().FindOrAddTypeNode(L"double", Type::Make<double>());
				GetGlobleNamespaceRef().FindOrAddTypeNode(L"float", Type::Make<float>());
				GetGlobleNamespaceRef().FindOrAddTypeNode(L"long double", Type::Make<long double>());
				GetGlobleNamespaceRef().FindOrAddTypeNode(L"bool", Type::Make<bool>());
			}
			return StaticTypes;
		}
		TypeLibrary::TypeLibrary() :GlobleNamespace(), Separator(L".") { }
		ptr<TypeLibrary> GetGlobleLibrary()
		{
			static ptr<TypeLibrary>*p;
			if (p)return *p;
			SpinMutex::GetDefaultRef().Lock();
			if (!p) {
				static ptr<TypeLibrary> lib = new TypeLibrary();
				p = &lib;
			}
			SpinMutex::GetDefaultRef().UnLock();
			return *p;
		}
		TypeLibrary::~TypeLibrary()
		{
			if(GlobleNamespace!=null)GlobleNamespace.Clear();
		}
	}
}
#endif
